
#ifndef SETTINGS_H
#define SETTINGS_H

#include <BTable>
#include <BColor>
#include <BObject>
#include <BXmlNode>
#include <BString>

using namespace BWE;

typedef BMap<BString, BColor>	ColorGroup;
typedef BTable<BString>			StringTable;

static inline bool StringToColor(BString& text, BColor& color)
{
	text.trimmed();
	if (text.empty())
		return false;
	if (text == "none" || text == "empty")
	{
		color.set(0, 0, 0, 0);
		return true;
	}
	if (text.beginWith('#'))
	{
		text.remove('#');
		if (text.size() == 6)
		{
			color.r() = bHexToByte(text.cstr());
			color.g() = bHexToByte(text.cstr() + 2);
			color.b() = bHexToByte(text.cstr() + 4);
			color.a() = 255;
			return true;
		}
		if (text.size() == 8)
		{
			color.r() = bHexToByte(text.cstr());
			color.g() = bHexToByte(text.cstr() + 2);
			color.b() = bHexToByte(text.cstr() + 4);
			color.a() = bHexToByte(text.cstr() + 6);
			return true;
		}
		return false;
	}
	if (text.beginWith("rgb("))
	{
		int begin = text.find('(');
		text.remove(0, begin + 1);
		int end = text.find(')');
		text.remove(end, text.size());
		BStringArray words;
		text.split(words, ',');
		if (words.size() == 3)
		{
			color.r() = words[0].toInt();
			color.g() = words[1].toInt();
			color.b() = words[2].toInt();
			color.a() = 255;
			return true;
		}
		return false;
	}
	if (text.beginWith("rgba("))
	{
		int begin = text.find('(');
		text.remove(0, begin + 1);
		int end = text.find(')');
		text.remove(end, text.size());
		BStringArray words;
		text.split(words, ',');
		if (words.size() == 4)
		{
			color.r() = words[0].toInt();
			color.g() = words[1].toInt();
			color.b() = words[2].toInt();
			color.a() = words[3].toInt();
			return true;
		}
		return false;
	}
	if (text.contain(','))
	{
		BStringArray words;
		text.split(words, ',');
		if (words.size() < 3 || words.size() > 4)
			return false;
		color.r() = words[0].toInt();
		color.g() = words[1].toInt();
		color.b() = words[2].toInt();
		color.a() = 255;
		if (words.size() == 4)
			color.a() = words[3].toInt();
		return true;
	}
	text.lower();
	return false;
}

class Settings : public BObject
{
public:
	Settings();
	~Settings();

	bool load();
	bool save();

	void dirty() const;
	bool isDirty() const;

	void setLanguage(const BString& language);
	const BString& language() const;

	void setThemeStyle(const BString& themeStyle);
	const BString& themeStyle() const;

	void setShowTabs(bool show);
	bool showTabs() const;

	void setShowSpaces(bool show);
	bool showSpaces() const;

	void setShowReturns(bool show);
	bool showReturns() const;

	void setShowLinefeeds(bool show);
	bool showLinefeeds() const;

	void setColorGroup(const BString& type, const ColorGroup& colorGroup);
	const ColorGroup& colorGroup(const BString& type);

	void setColor(const BString& type, const BString& name, const BColor& color);
	const BColor& color(const BString& type, const BString& name) const;

	bool assignColor(const BString& type, const BString& name, BColor& color);

	void setExtentionTable(const StringTable& extentionTable);
	const StringTable& extentionTable() const;

private:
	mutable bool	_dirty;

	BString			_language;
	BString			_themeStyle;

	bool			_showTabs;
	bool			_showSpaces;
	bool			_showReturns;
	bool			_showLinefeeds;

	StringTable		_extentionTable;
	BMap<BString, ColorGroup>		_colorGroupMap;
};

#endif
